home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9207.ZIP / AVKCAPT.ZIP / COPYLIST.C < prev    next >
Text File  |  1992-03-18  |  24KB  |  713 lines

  1. //-------------------------------------------------------------------------
  2. //            ActionMedia II Programmer's Toolkit
  3. //            
  4. //            Windows Sample Code Shared Functions
  5. //
  6. // Module Name:    copylist.c
  7. //
  8. // Description:    Create a copy list for a given connector destination box.
  9. //
  10. //     Copyright Intel Corp. 1991, 1992
  11. //    All Rights Reserved.
  12. //
  13. //-------------------------------------------------------------------------
  14. //
  15. // Exported functions from this module:
  16. //
  17. //        UpdateCopyList
  18. //
  19. //-------------------------------------------------------------------------
  20. //    NOTES ON CopyList
  21. //    
  22. //    The function UpdateCopyList is called by a Windows timer at set
  23. //    intervals.  It runs through the portion of the Window Manager's list 
  24. //    windows that are 'above' the target AVK window on the desktop. It
  25. //    checks each active window found for overlap with the target window.
  26. //    If the active window overlaps, it extracts the intersecting rectangle
  27. //    and adds it to a clip list.  If the clip list has changed or the target 
  28. //    rectangle has changed since the last timer tick, it calls Clip2Copy()
  29. //    to produce a copylist and then passes the copylist to the AVK 
  30. //    connector.
  31. //
  32. //    The function Clip2Copy() converts a clip list to a copy list.  A clip
  33. //    is an array of rectangles which are to be EXCLUDED from the AVK display 
  34. //    in a given area of a view. AVK's call AvkConnCopyList() passes its 
  35. //    connector an array    of rectangles defining the areas to be INCLUDED in 
  36. //    the AVK display. The diagram shows a large box where a AVK image is 
  37. //    being displayed, overlaid by a smaller dialog box. To prevent the AVK 
  38. //    image from showing through the black lettering in the dialog box 
  39. //    (speckling), we must create a copy list of the areas not encompassed by 
  40. //    the dialog box.  The code below takes the BOX structures defining the 
  41. //    AVK window and the overlapping dialog box window (and any other 
  42. //    overlapping windows) and produces an array of boxes to be included in 
  43. //    the copy list (shown by the dotted lines and named Include box 1-4).  
  44. //    This is creation of a copy list in its simplest    form.
  45. //
  46. //          AVK Window A
  47. //        +--------------------------------------------------+
  48. //        |                                                  |
  49. //        |                                                  |
  50. //        |                                                  |
  51. //        |                                                  |
  52. //        |             Include box 1                        |
  53. //        |                                                  |
  54. //        |                                                  |
  55. //        |..........+-----------------------+...............|
  56. //        |          |                       |               |
  57. //        |          |                       |               |
  58. //        |          |                       |               |
  59. //        |          |                       |               |
  60. //        |          |                       |               |
  61. //        |          |                       |               |
  62. //        | Include  | Overlapping window B  | Include box 3 |
  63. //        | box 2    |                       |               |
  64. //        |          |                       |               |
  65. //        |          | Region to be excluded |               |
  66. //        |          |                       |               |
  67. //        |          |                       |               |
  68. //        |          |                       |               |
  69. //        |          |                       |               |
  70. //        |          |                       |               |
  71. //        |..........+-----------------------+...............|
  72. //        |                                                  |
  73. //        |                                                  |
  74. //        |             Include box 4                        |
  75. //        |                                                  |
  76. //        |                                                  |
  77. //        |                                                  |
  78. //        +--------------------------------------------------+
  79. //
  80. //
  81. //
  82. //    In the case where there is only one overlapping box, building the copy
  83. //    list is quite straightforward.  The four copy boxes would have the
  84. //    x/y coordinates as follows:
  85. //
  86. //        box 1 = A.x1/A.y1 A.x2/B.y1
  87. //        box 2 = A.x1/B.y1 B.x1/B.y2
  88. //        box 3 = A.x1/B.y2 A.x2/A.y2
  89. //        box 4 = B.x1/B.y1 A.x2/B.y2
  90. //
  91. //    When there are 2 or more overlapping boxes, it is more complicated
  92. //    as the included areas must be subdivided into smaller rectangles
  93. //    based on the number, sizes and positions of the overlapping boxes.
  94. //    
  95. //    The code below creates an array of the x coordinates of all boxes 
  96. //    (including the AVK window) and an array of all y coordinates.  It 
  97. //    then sorts the two arrays into ascending order. It can then extract 
  98. //    from these arrays a matrix of boxes describing the entire AVK window 
  99. //    where each box is either an INCLUDING or EXCLUDING region.  It then 
  100. //    goes through the matrix and determines if each box is in fact one of 
  101. //    the overlapping boxes passed in by the user.  If not, the box is an 
  102. //    INCLUDING region and is added to the copy list.  When done, the copy 
  103. //    list is ready to pass to AvkConnCopyList().
  104. //
  105. //    Note that in the case diagrammed above, this algorithm would produce a 
  106. //    copy list of 8 smaller boxes instead of the four pictured above and
  107. //    would look like this:
  108. //    
  109. //          AVK Window A
  110. //        +--------------------------------------------------+
  111. //        |          .                       .               |
  112. //        | Include  .  Include box 2        . Include box 3 |
  113. //        | box 1    .                       .               |
  114. //        |          .                       .               |
  115. //        |          .                       .               |
  116. //        |          .                       .               |
  117. //        |          .                       .               |
  118. //        |..........+-----------------------+...............|
  119. //        |          |                       |               |
  120. //        |          |                       |               |
  121. //        |          |                       |               |
  122. //        |          |                       |               |
  123. //        |          |                       |               |
  124. //        |          |                       |               |
  125. //        | Include  | Overlapping window B  | Include box 5 |
  126. //        | box 4    |                       |               |
  127. //        |          |                       |               |
  128. //        |          | Region to be excluded |               |
  129. //        |          |                       |               |
  130. //        |          |                       |               |
  131. //        |          |                       |               |
  132. //        |          |                       |               |
  133. //        |          |                       |               |
  134. //        |..........+-----------------------+...............|
  135. //        |          .                       .               |
  136. //        |          .                       .               |
  137. //        | Include  .  Include box 7        . Include box 8 |
  138. //        | box 6    .                       .               |
  139. //        |          .                       .               |
  140. //        |          .                       .               |
  141. //        +--------------------------------------------------+
  142. //
  143. //    This method produces more boxes than is necessary to describe the
  144. //    INCLUDE space.  We can minimize this problem by combining adjacent
  145. //    INCLUDE rectangles as we scan the matrix and make up the copy list.
  146. //    We don't try to do a best fit analysis coalescing the rectangles
  147. //    since it would add both code complexity and processing time.  We just
  148. //    combine rectangles that are horizontally adjacent since we are processing
  149. //    them in horizontal order.  This will result in either the minimum 
  150. //    necessary rectangles or close enough to the minimum. In the case of
  151. //    two clip windows overlapping each other, 18 rectangles are created and
  152. //    then coalesced into 8. The best case here would have been 6.
  153. //
  154. //    NOTA BENE:  This function assumes that the boxes in the caller's clip
  155. //    list are all truncated to the borders of the AVK window for whom we
  156. //    are preparing the copy list.  Callers can truncate by hand or use the
  157. //    Windows function IntersectRect() to do the work for them.  Note the use
  158. //    of a cast with the Windows function SetRect() below to make it operate
  159. //    on a BOX structure as an example.  Truncation can be added easily, if
  160. //    desired, by simply using the coordinates in the pWin rectangle as
  161. //    bounding coordinates and truncating any clip box coordinates that
  162. //    fall outside this range (perhaps in the AddBoxCoords() function).
  163. //
  164. //-------------------------------------------------------------------------
  165.  
  166. #include <windows.h>
  167. #include <stdlib.h>
  168. #include "avkapi.h"
  169. #define COPYLIST_NOEXTERNS    1
  170. #include "copylist.h"
  171.  
  172. static BOX        CopyList[NUM_COPY_BOXES];
  173. static WORD        CopyCnt;
  174.  
  175. #define    NUM_COORDS    (NUM_CLIP_RECTS << 1)
  176.  
  177. static int        xCoords[NUM_COORDS];
  178. static int        yCoords[NUM_COORDS];
  179.  
  180. static WORD        xCnt;
  181. static WORD        yCnt;
  182.  
  183. static WORD        cxScreen = 0;
  184. static WORD        cyScreen = 0;
  185. static double    xDelta;
  186. static double    yDelta;
  187.  
  188. static BOOL     Clip2Copy(BOX *, BOX *, WORD);
  189. static BOOL        InClipList(int, int, BOX *, WORD);
  190. static void        BuildCoordArrays(BOX *, BOX *, WORD);
  191. static void        AddBoxCoords(BOX *);
  192. static int        fnCmpWords(const int *, const int *);
  193. static void        Win2AvkCoords(RECT *, BOX *);
  194.  
  195.  
  196. //-------------------------------------------------------------------------
  197. //FUNCTION:
  198. //    
  199. //    BOOL UpdateCopyList(pCopyList, prectTarget, cxView, cyView, BOOL *pbUpdated)
  200. //
  201. //PARMS IN:
  202. //
  203. //    COPYLIST *pCopyList        pointer to COPYLIST structure that identifies
  204. //                            a rectangle being used as an AVK connector
  205. //                            destination.
  206. //    
  207. //    RECT *prectTarget        pointer to a RECT structure describing the
  208. //                            dimensions of the destination box (in AVK
  209. //                            coordinates) of the connector to be clipped.
  210. //
  211. //    WORD cxView                x resolution of the AVK view plane - needed
  212. //                            to scale Windows RECT coordinates to AVK
  213. //                            BOX coordinates
  214. //
  215. //    WORD cyView                y resolution of the AVK view plane - needed
  216. //                            to scale Windows RECT coordinates to AVK
  217. //                            BOX coordinates
  218. //
  219. //PARMS OUT:
  220. //
  221. //    BOOL *pbUpdated            TRUE if copylist updated. FALSE if no changes.
  222. //
  223. //DESCRIPTION:
  224. //
  225. //    Make a list of the intersecting rectangles that occlude our AVK
  226. //    destination box and create a copylist to be passed to the AVK
  227. //    box's connector.  This process is driven by a Windows timer.
  228. //
  229. //RETURN:
  230. //    0         if successful
  231. //    0xffff    if Clip2Copy error
  232. //    Anything else is an AVK error.
  233. //
  234. //-------------------------------------------------------------------------
  235.  
  236. I16
  237. UpdateCopyList(COPYLIST *pCopyList, RECT *prectTarget, WORD cxView, WORD cyView,
  238.     BOOL *pbUpdated)
  239. {
  240.     BOOL        bUpdateCopyList;    // TRUE if new copylist was created
  241.     WORD        ClipCnt = 0;        // number of clip boxes made
  242.     I16            rc;                    // return code
  243.     HWND        hwndCurr;            // handle of current window being checked
  244.     RECT        rectCurr;            // dimensions of hwndCurr
  245.     RECT        rectIntersect;        // intersection of a window and the
  246.                                     //   AVK destination rectangle
  247.  
  248.     rc = AVK_ERR_OK;
  249.  
  250.     //    If this view has no video connector (for example, in the case of
  251.     //    an audio-only file), no clipping needed.
  252.  
  253.     if (pCopyList->hConn == (HAVK)0)
  254.         return  rc;
  255.  
  256.     CopyCnt = 0;
  257.  
  258.     *pbUpdated = FALSE;
  259.  
  260.     //    Set up for RECT to BOX conversion.
  261.  
  262.     //    Get the screen coordinates the first time in.
  263.  
  264.     if (!cxScreen)
  265.     {
  266.         cxScreen = GetSystemMetrics(SM_CXSCREEN);
  267.         cyScreen = GetSystemMetrics(SM_CYSCREEN);
  268.     }
  269.  
  270.     //    Compute the delta values to convert from screen to view coordinates.
  271.  
  272.     xDelta = ((double)cxView / (double)cxScreen);
  273.     yDelta = ((double)cyView / (double)cyScreen);
  274.  
  275.     //    Start enumerating windows from our display window.
  276.  
  277.     hwndCurr = pCopyList->hwndTarget;
  278.  
  279.     //    Init update flag - will be TRUE if there is any change in the 
  280.     //    clip list from last time this was done.
  281.  
  282.     bUpdateCopyList = FALSE;
  283.  
  284.     //    Now walk through the windows that are 'above' our display window
  285.     //    and find any that overlap.  For each overlapping window, get 
  286.     //    the actual intersection and add it to the clip list.  Note that
  287.     //    we compare each intersecting rectangle with the one already in 
  288.     //    the clip list at the current position. If they are different, 
  289.     //    or we don't have any current entry in that slot, we set the
  290.     //    flag to indicate that the clip list has changed. Only if the copylist
  291.     //    has changed do we create a new copy list.  Otherwise, there is
  292.     //    no need to update the copylist at this time.
  293.  
  294.     while (hwndCurr = GetNextWindow(hwndCurr, GW_HWNDPREV))
  295.     {
  296.         //    Only worry about it if it is visible.
  297.  
  298.         if (IsWindowVisible(hwndCurr))
  299.         {
  300.             //    Get its dimensions and convert to AVK coords.
  301.  
  302.             GetWindowRect(hwndCurr, &rectCurr);
  303.             Win2AvkCoords(&rectCurr, (BOX *)&rectCurr);
  304.  
  305.             //    Only worry about it if it intersects. Extract 
  306.             //    the intersecting rectangle.
  307.  
  308.             if (IntersectRect(&rectIntersect, &rectCurr, prectTarget))
  309.             {
  310.                 //    If we had a previous rect in the copy list and
  311.                 //    it was the same size, don't bother to copy it.  
  312.                 //    If it was a different size, copy it and set the
  313.                 //    flag to tell us that the list has changed.
  314.  
  315.                 if (ClipCnt < pCopyList->ClipCnt)
  316.                 {
  317.                     if (!EqualRect(&pCopyList->rectClipList[ClipCnt], 
  318.                       &rectIntersect))
  319.                     {
  320.                         bUpdateCopyList = TRUE;
  321.                         CopyRect(&pCopyList->rectClipList[ClipCnt], 
  322.                           &rectIntersect);
  323.                     }
  324.  
  325.                 }
  326.                 else
  327.                 {
  328.                     //    This rect has no counterpart in the old copy
  329.                     //    list since we are past the end of the old list
  330.                     //    , so we KNOW that the list has changed. Copy it 
  331.                     //    in and set the changed flag.
  332.  
  333.                     bUpdateCopyList = TRUE;
  334.                      CopyRect(&pCopyList->rectClipList[ClipCnt], 
  335.                       &rectIntersect);
  336.                 }
  337.  
  338.                 //    If we run out of elements in the list, then
  339.                 //    just stop finding more rects.  We will only
  340.                 //    use the ones found.
  341.  
  342.                 if (++ClipCnt >= NUM_CLIP_RECTS)
  343.                     hwndCurr = NULL;
  344.             }
  345.         }
  346.     }
  347.  
  348.     //    If we finish with a different number than last time, we know the
  349.     //    list is changed. Flag it.  We need this check since a new list
  350.     //    in which each box is identical to its counterpart in the old
  351.     //    list, but where there are fewer boxes in the new list will not
  352.     //    have been flagged above.
  353.  
  354.     if (ClipCnt != pCopyList->ClipCnt)
  355.         bUpdateCopyList = TRUE;
  356.  
  357.     //    Check whether the destination box has changed since the last
  358.     //    time.  A change will trigger a copylist update even if the
  359.     //    copylist itself has not changed. Update the stored target
  360.     //    rectangle with the new values.
  361.  
  362.     if (!EqualRect(&pCopyList->rectTarget, prectTarget))
  363.     {
  364.         CopyRect(&pCopyList->rectTarget, prectTarget);
  365.         bUpdateCopyList = TRUE;
  366.     }
  367.  
  368.     //    Update the number of clip rects now in the rectClipList array.
  369.  
  370.     pCopyList->ClipCnt = ClipCnt;
  371.  
  372.     //    At this point, we have build a new clip list of intersecting
  373.     //    rectangles.  If the list has changed in any way from the
  374.     //    last one, then we convert the copylist to a copylist.
  375.  
  376.     if (bUpdateCopyList)
  377.     {
  378.         //    Nothing in the copylist as yet.
  379.  
  380.         CopyCnt = 0;
  381.  
  382.         //    If we have any overlapping rectangles in the clip list,
  383.         //    create a copylist from the copylist.
  384.  
  385.         if (ClipCnt)
  386.         {
  387.             if (!Clip2Copy((BOX *)prectTarget, (BOX *)pCopyList->rectClipList, 
  388.               ClipCnt))
  389.                   return COPY_ERROR;
  390.         }
  391.         else
  392.         {
  393.             //    If no clip rectangles were found, create a copy list of one 
  394.             //    element, the entire target rectangle.  This will remove the 
  395.             //    old copy list and make the whole view region visible.
  396.  
  397.             CopyCnt = 1;
  398.             CopyRect((RECT *)CopyList, prectTarget);
  399.         }
  400.  
  401.         //    Now call AVK and pass the copy list down to microcode.
  402.  
  403.         if ((rc = AvkConnCopyList(pCopyList->hConn, CopyCnt, CopyList, 
  404.           AVK_TIME_IMMEDIATE)) == AVK_ERR_OK)
  405.               *pbUpdated = TRUE;
  406.     }
  407.     return rc;
  408. }
  409.  
  410.  
  411. //-------------------------------------------------------------------------
  412. //FUNCTION:
  413. //
  414. //    Clip2Copy(pWin, pClip, nClip)
  415. //
  416. //PARMS IN:
  417. //
  418. //    BOX  *pWin;        address of the destination box of the connector that 
  419. //                        you are preparing this copy list for.
  420. //    BOX  *pClip;    address of an array of box pointers containing the
  421. //                        overlapping boxes
  422. //    WORD   nClip;    number of boxes in the pClip array. 
  423. //                        Must be <= NUM_CLIP_RECTS
  424. //
  425. //DESCRIPTION:
  426. //    
  427. //    Takes an array of boxes overlapping the AVK window in the view 
  428. //    representing the areas to be EXCLUDED from the AVK display and
  429. //    builds an array of boxes representing the areas to be INCLUDED
  430. //    in the AVK display (all areas NOT covered by the overlapping boxes).
  431. //    
  432. //RETURN:
  433. //
  434. //    TRUE if successful.
  435. //    FALSE if caller specified too many clip boxes or if it would result 
  436. //        in too many copy boxes (CopyCnt > NUM_COPY_BOXES).
  437. //
  438. //-------------------------------------------------------------------------
  439.  
  440. BOOL
  441. Clip2Copy(BOX *pWin, BOX *pClip, WORD nClip)
  442. {
  443.     int        nCopy;
  444.     WORD    x, y;
  445.     BOOL    bLastBoxIncluded;
  446.  
  447.     if (nClip > NUM_CLIP_RECTS)
  448.         return FALSE;
  449.  
  450.     //    First, build the sorted arrays of x and y coordinates.
  451.  
  452.     BuildCoordArrays(pWin, pClip, nClip);
  453.  
  454.     nCopy = -1;        // start below 0 - will be incremented before
  455.                      // being used!
  456.  
  457.     for (y = 0; y < (yCnt - 1); y++)
  458.     {
  459.         //    If we have two boxes sharing the same y coordinate, we have
  460.         //    a duplicate y coordinate in the array and would produce
  461.         //    an extra erroneous 1-line high include box.  Just skip it.
  462.  
  463.         if (yCoords[y] == yCoords[y + 1])
  464.             continue;
  465.  
  466.         //    We are starting a new horizontal level, so make sure we
  467.         //    indicate that we shouldn't try to coalesce this box with
  468.         //    the prior one.
  469.  
  470.         bLastBoxIncluded = FALSE;
  471.  
  472.         for (x = 0; x < (xCnt - 1); x++)
  473.          {
  474.             //    Duplicate x coords should be skipped as well.
  475.  
  476.             if (xCoords[x] == xCoords[x + 1])
  477.                 continue;
  478.  
  479.             //    If the box is not in the clip list, we will include
  480.             //    it in the copy list.  
  481.             
  482.             if (!InClipList(xCoords[x], yCoords[y], pClip, nClip))
  483.             {
  484.                 //    Combine horizontally adjacent rectangles. 
  485.                 //    If the last rectangle we processed on this level
  486.                 //    was included in the copy list, just stretch its
  487.                 //    x2 coordinate to cover this one too.  If the
  488.                 //    prior box was not put into the copy list, we have
  489.                 //    to make a new entry for this box.
  490.  
  491.                 if (bLastBoxIncluded)
  492.                     CopyList[nCopy].x2 = xCoords[x + 1];
  493.                 else
  494.                 {
  495.                     //  Exit with an error if we are about to overrun
  496.                     //    the copy list maximum.
  497.  
  498.                     if (++nCopy >= NUM_COPY_BOXES)
  499.                         return FALSE;
  500.  
  501.                     //     We are entering a new rectangle in the copy 
  502.                     //    list.  Increment the subscript for it. 
  503.  
  504.                     SetRect((RECT *)&CopyList[nCopy], 
  505.                       xCoords[x], yCoords[y],
  506.                       xCoords[x+1], yCoords[y+1]);
  507.  
  508.                     //    Turn on the flag to indicate that adjacent
  509.                     //    rectangles should be coalesced with this one
  510.                     //    instead of being added as separate rectangles.
  511.  
  512.                     bLastBoxIncluded = TRUE;
  513.                 }
  514.  
  515.             }
  516.             else
  517.                 //  This rectangle is not being added. Force next 
  518.                 //    acceptable rectangle to be added as a new rectangle 
  519.                 //    instead of being combined.
  520.  
  521.                 bLastBoxIncluded = FALSE;    
  522.         }
  523.     }
  524.  
  525.     //    We have been using nCopy as the subscript.  Increment by one
  526.     //    to make the actual number of elements added.
  527.  
  528.     CopyCnt = (WORD)nCopy + 1;
  529.  
  530.     return TRUE;
  531. }
  532.  
  533. //-------------------------------------------------------------------------
  534. //FUNCTION:
  535. //    
  536. //    BuildCoordArrays(pWin, pClip, nClip)
  537. //
  538. //PARMS IN:
  539. //
  540. //    BOX  *pWin;        address of the destination box of the connector that 
  541. //                        you are preparing this copy list for.
  542. //    BOX  *pClip;    address of an array of box pointers containing the
  543. //                        overlapping boxes
  544. //    WORD   nClip;    number of boxes in the pClip array. 
  545. //                        Must be <= NUM_CLIP_RECTS
  546. //
  547. //DESCRIPTION:
  548. //
  549. //    Builds two coordinate arrays.  xCoord[] holds all of the x1 and x2 
  550. //    values from the display window and all clip boxes.  yCoord[] holds 
  551. //    all of the y coordinates.  Both coordinate arrays are then sorted 
  552. //    into ascending order.  We can now use them to break the connector
  553. //    destination box down into a matrix of INCLUDED and EXCLUDED boxes
  554. //    as in the second diagram above.
  555. //
  556. //RETURN:
  557. //
  558. //    None
  559. //
  560. //-------------------------------------------------------------------------
  561.  
  562.  
  563. static void
  564. BuildCoordArrays(BOX *pWin, BOX *pClip, WORD nClip)
  565. {
  566.     WORD        i;
  567.  
  568.     //    Zero out the x and y coord counters.  These are the subscripts
  569.     //    into the xCoord[] and yCoord[] arrays and are incremented in
  570.     //    AddBoxCoords().
  571.  
  572.     xCnt = yCnt = 0;
  573.  
  574.     //    Start by adding the x/y coordinates of the AVK window to the
  575.     //    xCoord[] and yCoord[] arrays. These are necessary as the  
  576.     //    bounding coordinates.
  577.  
  578.     AddBoxCoords(pWin);
  579.  
  580.     //    Now add the coordinates of all of the clip boxes.
  581.  
  582.     for (i = 0; i < nClip; i++)
  583.         AddBoxCoords(&pClip[i]);
  584.  
  585.     //    Sort the xCoord[] and yCoord[] arrays into ascending order.
  586.  
  587.     qsort(xCoords, xCnt, sizeof(int), fnCmpWords);
  588.     qsort(yCoords, xCnt, sizeof(int), fnCmpWords);
  589. }
  590.  
  591.  
  592. //-------------------------------------------------------------------------
  593. //FUNCTION:
  594. //    
  595. //    AddBoxCoords(pBox)
  596. //
  597. //PARMS IN:
  598. //
  599. //    BOX  *pBox;        pointer to a box whose coordinates are to be added
  600. //                        to the xCoords[] and yCoords[] arrays.
  601. //
  602. //DESCRIPTION:
  603. //
  604. //    Adds the x1 and x2 coords into the xCoords[] array and the y1 and
  605. //    y2 coords into the yCoords[] array.
  606. //
  607. //    xCnt and yCnt are incremented for each coordinate added.
  608. //
  609. //RETURN:
  610. //
  611. //    None
  612. //
  613. //-------------------------------------------------------------------------
  614.  
  615.  
  616. static void
  617. AddBoxCoords(BOX *pBox)
  618. {
  619.     //    Add the box's x coordinates to the xCoord[] array.
  620.  
  621.     xCoords[xCnt++] = pBox->x1;
  622.     xCoords[xCnt++] = pBox->x2;
  623.  
  624.     //    Add the box's y coordinates to the yCoord[] array.
  625.  
  626.     yCoords[yCnt++] = pBox->y1;
  627.     yCoords[yCnt++] = pBox->y2;
  628. }
  629.  
  630. //-------------------------------------------------------------------------
  631. //FUNCTION:
  632. //    
  633. //    InClipList(x, y, pClip, nClip)
  634. //
  635. //PARMS IN:
  636. //
  637. //    int   x;         x coordinate of point to be tested
  638. //    int   y;         y coordinate of point to be tested
  639. //    BOX  *pClip;     address of the array of pointers to clip list boxes
  640. //    WORD  nClip;    number of boxes in the pClip array. 
  641. //
  642. //DESCRIPTION:
  643. //
  644. //    Builds a POINT structure from the x,y coordinates and tests whether
  645. //    this point is in any of the boxes in the clip list array.
  646. //
  647. //RETURN:
  648. //
  649. //    TRUE if the point is within (or on the top or left edge) of any of
  650. //        the boxes in the clip list.
  651. //    FALSE if not.
  652. //
  653. //-------------------------------------------------------------------------
  654.  
  655. static BOOL
  656. InClipList(int x, int y, BOX *pClip, WORD nClip)
  657. {
  658.     WORD        i;
  659.     POINT    Point;
  660.  
  661.     Point.x = x;
  662.     Point.y = y;
  663.  
  664.     for (i = nClip; i; i--, pClip++)
  665.     {
  666.         if (PtInRect((LPRECT)pClip, Point))
  667.             return TRUE;
  668.     }
  669.     return FALSE;
  670. }
  671.  
  672.  
  673. //-------------------------------------------------------------------------
  674. //FUNCTION:
  675. //    
  676. //    fnCmpWords(pElm1, pElm2)
  677. //
  678. //PARMS IN:
  679. //
  680. //    WORD *pElm1;    pointer to first element to be compared
  681. //    WORD *pElm2;    pointer to second element to be compared
  682. //
  683. //DESCRIPTION:
  684. //
  685. //    Function to compare two WORDs for qsort().
  686. //
  687. //RETURN:
  688. //
  689. //    <0 if first value less than second.
  690. //    0  if both values equal
  691. //    >0 if first value greater than second.
  692. //
  693. //-------------------------------------------------------------------------
  694.  
  695. static int
  696. fnCmpWords(const int *pElm1, const int *pElm2)
  697. {
  698.     return *pElm1 - *pElm2;
  699. }
  700.  
  701.  
  702. static VOID
  703. Win2AvkCoords(RECT *pRect, BOX *pBox)
  704. {
  705.     pBox->x1 = (I16)((double)pRect->left   * xDelta);
  706.     pBox->y1 = (I16)((double)pRect->top    * yDelta);
  707.     pBox->x2 = (I16)((double)pRect->right  * xDelta);
  708.     pBox->y2 = (I16)((double)pRect->bottom * yDelta);
  709. }
  710.  
  711.  
  712.  
  713.